//
//  HTPlayerView.swift
//  MagaCore
//
//  Created by qmdjx on 2023/5/20.
//

import SwiftUI
import AVKit
import AppLovinSDK
import Combine

struct HTPlayerView: View {
    let var_margin: CGFloat = 15
    let var_progressWidth: CGFloat = var_screenWidth - 2*15 - 22*2 - 57*2 - 16*2
    let var_progressLandsWidth: CGFloat = var_screenHeight - 60*2 - 30*2 - 12
    
    @Binding var var_animeInfo: HTAnime?
    @Binding var var_animeTitle: String
    @Binding var var_url: String
    @Binding var var_changeUrl: HTChangeUrl?
    @Binding var var_orientation: UIDeviceOrientation
    @Binding var var_selectEP: (() -> Void)!
    @Binding var var_nextEP: (() -> Void)!
    @Binding var var_subTitleBtnClick: (() -> Void)!
    @Binding var var_fullScreen: ((UIDeviceOrientation) -> Void)!
    @Binding var var_subtitleList: [HTSubtitle]?
    @Binding var var_subState: HTEnumSubtitleState!
    @Binding var var_palyerCurrentTime: Double!
    @Binding var var_delay: Double!
    @Binding var var_progressRate: Double!
    @Binding var var_startTime: String
    @Binding var var_seekTime: Int
    @Binding var var_during: Double
    @Binding var var_selEp: HTEp!
    @Binding var var_source: String
    @Binding var var_isLock: Bool
    @Binding var var_curSubscribe: HTSubscribe?
    
    @EnvironmentObject private var var_store: HTAppStore
    @State private var var_palyer = AVPlayer()
    @State private var var_isShowControls = true
    @State private var var_isSuspend = true        // 是否暂停
    @State private var var_endTime = "00:00"
    @State private var var_fastState: HTEnumFast = .htEnumNone
    @State private var var_subText = ""
    @State private var var_oldX: CGFloat = 0.0
    @State private var var_oldY: CGFloat = 0.0
    @State private var var_timeObserver: Any!
    @State private var var_pushToPremium: () -> Void = {}
    @State private var var_showPushToPremium = false
    @State private var var_showRewardedAd: Bool = false
    @State private var var_showInterstitialAd: Bool = false
    @State private var var_viewDisappear: Bool = false
    @State private var var_brightnessLevel: Double = 0.0
    @State private var var_showProgress: Bool = false
    @State private var var_showBrightness: Bool = false
    @State private var var_showVolume: Bool = false
    @State private var var_showActivityIndicator: Bool = false
    @State private var currentTime: Double = 0.0
    @State private var timer: Timer?
    @State private var timeObserver: Any?
    @State private var lastTriggeredMinute = -1
    
    init(
        var_animeInfo: Binding<HTAnime?>,
        var_animeTitle: Binding<String>,
        var_url: Binding<String>,
        var_changeUrl: Binding<HTChangeUrl?>,
        var_orientation: Binding<UIDeviceOrientation>,
        var_selectEP: Binding<(() -> Void)?>,
        var_nextEP: Binding<(() -> Void)?>,
        var_subTitleBtnClick: Binding<(() -> Void)?>,
        var_fullScreen: Binding<((UIDeviceOrientation) -> Void)?>,
        var_subtitleList: Binding<[HTSubtitle]?>,
        var_subState: Binding<HTEnumSubtitleState?>,
        var_palyerCurrentTime: Binding<Double?>,
        var_delay: Binding<Double?>,
        var_progressRate: Binding<Double?>,
        var_startTime: Binding<String>,
        var_seekTime: Binding<Int>,
        var_during: Binding<Double>,
        var_selEp: Binding<HTEp?>,
        var_source: Binding<String>,
        var_isLock: Binding<Bool>,
        var_curSubscribe: Binding<HTSubscribe?>
    ) {        _var_animeInfo = var_animeInfo
        _var_animeTitle = var_animeTitle
        _var_url = var_url
        _var_changeUrl = var_changeUrl
        _var_orientation = var_orientation
        _var_selectEP = var_selectEP
        _var_nextEP = var_nextEP
        _var_subTitleBtnClick = var_subTitleBtnClick
        _var_fullScreen = var_fullScreen
        _var_subtitleList = var_subtitleList
        _var_subState = var_subState
        _var_palyerCurrentTime = var_palyerCurrentTime
        _var_delay = var_delay
        _var_progressRate = var_progressRate
        _var_startTime = var_startTime
        _var_seekTime = var_seekTime
        _var_during = var_during
        _var_selEp = var_selEp
        _var_source = var_source
        _var_isLock = var_isLock
        _var_curSubscribe = var_curSubscribe
    }
    
    var body: some View {
        VStack(spacing: 0){
            if var_orientation.isPortrait {
                Text("dfsdfsdf").frame(width: var_screenWidth, height: var_safeTop).background(Color.black)
            }
            
            ZStack(alignment: .center) {
                NavigationLink(destination: HTPremiumScreen(var_isPush: true), isActive: $var_showPushToPremium) {
                    EmptyView()
                }
                
                HTPalyer(var_palyer: $var_palyer, var_onTimeControlStatus: { newStatus in
                    if newStatus == .playing || newStatus == .paused {
                        var_showActivityIndicator = false
                    } else {
                        var_showActivityIndicator = true
                    }
                })
                .onTapGesture(count: 2) {
                    if var_isLock && var_orientation.isLandscape { return }
                    ht_startOrSuspend()
                }
                .onTapGesture {
                    print(UIDevice.ht_screenWidth(), UIDevice.ht_screenHeight())
                    var_isShowControls = !var_isShowControls
                }
                
                // 全屏
                if var_orientation.isLandscape {
                    HTControlFullView(var_palyer: $var_palyer, var_animeTitle: $var_animeTitle, var_selectEP: $var_selectEP, var_nextEP: $var_nextEP, var_subTitleBtnClick: $var_subTitleBtnClick, var_fullScreen: $var_fullScreen, var_subState: $var_subState, var_progressRate: $var_progressRate, var_startTime: $var_startTime, var_endTime: $var_endTime, var_during: $var_during, var_fastState: $var_fastState, var_isSuspend: $var_isSuspend, var_isShowControls: $var_isShowControls, var_isLock: $var_isLock, var_pushToPremium: $var_pushToPremium, var_onRemoveAd: {
                        HTNetworkManager().ht_requestForBuried(.htEnumMoviePlayCl(var_movie_id: var_animeInfo!.var_id, var_movie_name: var_animeInfo!.var_title ?? "", var_kid: "32", var_source: var_source, var_eps_id: var_selEp.var_id ?? "", var_eps_name: var_selEp.var_title ?? "", var_movielist_id: "", var_secname: "", var_subtitle: "1", var_m_type: "2", var_ori_type: "2"))
                    })
                }
                
                // 竖屏
                if var_orientation.isPortrait {
                    HTControlView(var_palyer: $var_palyer, var_subTitleBtnClick: $var_subTitleBtnClick, var_fullScreen: $var_fullScreen, var_subState: $var_subState, var_progressRate: $var_progressRate, var_startTime: $var_startTime, var_endTime: $var_endTime, var_during: $var_during, var_isSuspend: $var_isSuspend, var_isShowControls: $var_isShowControls)
                }
                
                if var_showBrightness {
                    HStack{
                        Image("brightness")
                            .frame(width: 24, height: 24)
                            .padding(.trailing, 5)
                            .padding(.leading, 15)
                        ProgressView(value: var_brightnessLevel, total: 1)
                            .accentColor(.white)
                            .background(Color(hex: "#ffffff").opacity(0.2))
                            .frame(width: 140)
                            .padding(.vertical, 20)
                            .padding(.trailing, 15)
                    }
                    .background(Color(hex: "#000000").opacity(0.5))
                    .cornerRadius(8)
                }
                
                if var_showActivityIndicator {
                    HTActivityIndicator(var_style: .medium)
                }
                
                // 字幕
                if var_subState == .htEnumOpen {
                    VStack{
                        Spacer()
                        Text(var_subText).ht_commonTextStyle(color: Color(hex: "FFFFFF"), fontSize: 16, weight: .bold)
                            .padding(.bottom, var_orientation.isPortrait ? 30 : 50)
                            .padding(.leading, var_margin)
                            .padding(.trailing, var_margin)
                        //              .lineLimit(1)
                    }
                    .zIndex(10)
                }
                
                // 左滑右滑快进快退
                if var_fastState != .htEnumNone {
                    VStack(spacing: 0) {
                        Group {
                            if var_fastState == .htEnumForward {
                                Image("fast_forward")
                                    .ht_resizeToFit()
                                    .frame(width: 54, height: 33)
                            } else if var_fastState == .htEnumBack {
                                Image("fast_back")
                                    .ht_resizeToFit()
                                    .frame(width: 54, height: 33)
                            }
                        }
                        Text(Int(var_progressRate * var_during).ht_formatTimeLine() + "/" + var_endTime)
                            .ht_commonTextStyle(color: Color(hex: "ffffff"), fontSize: var_h4, weight: .bold)
                            .padding(.top, 5)
                    }
                    .zIndex(10)
                }
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .background(Color.black)
            .gesture(DragGesture().onChanged({ val in
                if var_isLock && var_orientation.isLandscape { return }
                let var_width = var_orientation.isPortrait ? var_screenWidth : var_screenHeight
                let x = val.location.x
                let y = val.location.y
                let diffOldY = y - (var_oldY == 0.0 ? val.startLocation.y : var_oldY)
                let diffOldX = x - (var_oldX == 0.0 ? val.startLocation.x : var_oldX)
                var_oldX = x
                var_oldY = y
                
                if fabsf(Float(diffOldY)) > fabsf(Float(diffOldX)) && !var_showProgress {
                    if (x > var_width / 2) { // 右侧音量
                        var_showVolume = true
                        let var_space: Float = 0.03 // 控制幅度
                        let var_currentVolume: Float = HTTools.getSystemVolumValue()
                        HTTools.setSysVolum(diffOldY <= 0 ? (var_currentVolume + var_space) : (var_currentVolume - var_space))
                        if var_currentVolume < 0 {
                            HTTools.setSysVolum(0)
                        } else if var_currentVolume > 1 {
                            HTTools.setSysVolum(1)
                        }
                    } else { // 左侧亮度
                        var_showBrightness = true
                        let var_space: CGFloat = 0.05 // 控制幅度
                        UIScreen.main.brightness = diffOldY <= 0 ? (UIScreen.main.brightness + var_space) : (UIScreen.main.brightness - var_space)
                        if UIScreen.main.brightness < 0 {
                            UIScreen.main.brightness = 0
                        } else if UIScreen.main.brightness > 1 {
                            UIScreen.main.brightness = 1
                        }
                        var_brightnessLevel = UIScreen.main.brightness
                    }
                }
                
                if fabsf(Float(diffOldX)) > fabsf(Float(diffOldY)) && !var_showBrightness && !var_showVolume {
                    var_showProgress = true
                    let var_space: CGFloat = 2 // 控制幅度
                    if !var_isSuspend {
                        var_palyer.pause()
                    }
                    var_fastState = diffOldX > 0 ? .htEnumForward : .htEnumBack
                    var_progressRate += diffOldX / var_width / var_space
                    if var_progressRate > 1.0 {
                        var_progressRate = 1.0
                    } else if var_progressRate < 0.0 {
                        var_progressRate = 0.0
                    }
                }
            }).onEnded({ val in
                if var_isLock && var_orientation.isLandscape { return }
                let x = val.location.x
                let y = val.location.y
                let diffY = y - val.startLocation.y
                let diffX = x - val.startLocation.x
                if fabsf(Float(diffX)) > fabsf(Float(diffY)) {
                    ht_seek(second: var_during * var_progressRate)
                }
                if !var_isSuspend {
                    var_palyer.play()
                }
                var_fastState = .htEnumNone
                var_oldX = 0.0
                var_oldY = 0.0
                var_showProgress = false
                var_showVolume = false
                var_showBrightness = false
            }))
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        // 插屏广告播放
        .onReceive(NotificationCenter.default.publisher(for: HTConfig.STATIC_notification_interstitialAd), perform: { notification in
            if var_viewDisappear {return}
            if let userInfo = notification.userInfo {
                let value = userInfo["status"] as! String
                if (value == "show") {
                    var_showInterstitialAd = true
                    var_palyer.pause()
                    var_isSuspend = true
                } else if (value == "hide") {
                    var_showInterstitialAd = false
                    var_palyer.play()
                    var_isSuspend = false
                }
            }
        })
        // 激励视频播放
        .onReceive(NotificationCenter.default.publisher(for: HTConfig.STATIC_notification_rewardedAd), perform: { notification in
            if var_viewDisappear {return}
            if let userInfo = notification.userInfo {
                let value = userInfo["status"] as! String
                if (value == "show") {
                    var_showRewardedAd = true
                    var_palyer.pause()
                    var_isSuspend = true
                } else if (value == "hide") {
                    var_showRewardedAd = false
                    var_palyer.play()
                    var_isSuspend = false
                }
            }
        })
        // 开始播放
        .onReceive(NotificationCenter.default.publisher(for: .AVPlayerItemNewAccessLogEntry), perform: { obj in
            if var_viewDisappear {return}
            if (var_showRewardedAd || var_showInterstitialAd) {
                var_palyer.pause()
                var_isSuspend = true
            }
        })
        // 播放结束
        .onReceive(NotificationCenter.default.publisher(for: .AVPlayerItemDidPlayToEndTime), perform: { obj in
            if var_viewDisappear {return}
            var_isSuspend = true
            var_palyer.pause()
            HTNetworkManager().ht_requestForBuried(.htEnumPlayFinished(var_error_info: "success", var_youtubeid: var_animeInfo!.var_id , var_eps_id: var_selEp.var_id ?? "", var_play_url: var_url, var_m_type: "2"))
            if (!var_showRewardedAd && !var_showInterstitialAd) {
                var_nextEP!()
            }
        })
        // 程序进入到前台
        .onReceive(NotificationCenter.default.publisher(for: HTConfig.STATIC_notification_sceneActive), perform: { obj in
            if var_viewDisappear {return}
            var_palyer.play()
            var_isSuspend = false
        })
        .onAppear {
            var_viewDisappear = false
            if (var_palyer.rate == 0.0) {
                var_palyer.play()
                var_isSuspend = false
                var_isShowControls = false
            }
            
            // 切换地址回调
            var_changeUrl = {var_cloUrl in
                if var_cloUrl != "" {
                    print(var_cloUrl)
                    var_palyer.pause()
                    ht_checkVideo(palyer: var_palyer, url: var_url)
                }
            }
            
            let var_timeScale = var_palyer.currentItem?.asset.duration.timescale ?? 1
            // 播放进度监听
            var_timeObserver = var_palyer.addPeriodicTimeObserver(forInterval: CMTimeMake(value: Int64(1.0), timescale: var_timeScale), queue: DispatchQueue.main) { time in
                let var_currt = Double(CMTimeGetSeconds(time))
                var_progressRate = var_currt / (var_palyer.currentItem?.asset.duration.seconds)!
                var_startTime = Int(var_currt).ht_formatTimeLine()
                var_during = var_palyer.currentItem?.asset.duration.seconds ?? 0
                var_endTime = Int(var_palyer.currentItem?.asset.duration.seconds ?? 0).ht_formatTimeLine()
                // 调整字幕时间
                let var_adjustTime = Double(var_currt) + var_delay
                var_palyerCurrentTime = var_adjustTime
                for var_sub in var_subtitleList ?? [] {
                    if var_adjustTime > var_sub.var_startTime && var_adjustTime < var_sub.var_endTime {
                        var_subText = var_sub.var_text
                        break
                    } else {
                        var_subText = ""
                    }
                }
            }
            
            var_pushToPremium = {
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                    var_showPushToPremium = true
                    HTNetworkManager().ht_requestForBuried(.htEnumVipSh(var_source: "3"))
                }
            }
            
            ht_setupTimeObserver()
        }
        .onDisappear{
            var_viewDisappear = true
            var_isSuspend = true
            var_palyer.currentItem?.cancelPendingSeeks()
            var_palyer.currentItem?.asset.cancelLoading()
            var_palyer.removeTimeObserver(var_timeObserver as Any)
            NotificationCenter.default.removeObserver(self)
            ht_stopTimeObserver()
            
            if (var_animeInfo != nil) {
                HTNetworkManager().ht_requestForBuried(.htEnumMoviePlayCl(var_movie_id: var_animeInfo!.var_id , var_movie_name: var_animeInfo!.var_title ?? "", var_kid: "1", var_source: var_source, var_eps_id: var_selEp.var_id ?? "", var_eps_name: var_selEp.var_title ?? "", var_movielist_id: "", var_secname: "", var_subtitle: "1", var_m_type: "2", var_ori_type: var_orientation.isPortrait ? "1" : "2"))
            }
        }
    }
    
    func ht_setupTimeObserver() {
        let var_interval = CMTime(seconds: 1, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
        timeObserver = var_palyer.addPeriodicTimeObserver(forInterval: var_interval, queue: DispatchQueue.main) { var_time in
            let var_currentTime = Int(CMTimeGetSeconds(var_time))
            let var_currentMinute = Int(var_currentTime / 60)
            let var_minutes = (var_store.state.var_adState.var_adConfig?.var_banner_ad_secs)! / 60
            
            if var_currentMinute >= var_minutes && var_currentMinute % var_minutes == 0 && var_currentMinute != lastTriggeredMinute {
                // 执行操作，例如显示提示或执行特定任务
                print("Action executed at \(var_currentMinute) minute.")
                lastTriggeredMinute = var_currentMinute
                if (var_curSubscribe == nil) {
                    NotificationCenter.default.post(name: HTConfig.STATIC_notification_rewardedAd, object: nil, userInfo: ["status": "canshow"])
                }
            }
        }
    }
    
    func ht_stopTimeObserver() {
        if let observer = timeObserver {
            var_palyer.removeTimeObserver(observer)
            timeObserver = nil
        }
    }
    
    func ht_startOrSuspend() {
        if var_isSuspend {
            var_palyer.play()
            var_isSuspend = false
        } else {
            var_palyer.pause()
            var_isSuspend = true
        }
    }
    
    func ht_checkVideo(palyer: AVPlayer, url: String) {
        DispatchQueue.global(qos: .userInitiated).async {
            let var_asset = AVAsset(url: URL(string: url)!)
            let palyerItem = AVPlayerItem(asset: var_asset)
            for _ in var_asset.availableMediaCharacteristicsWithMediaSelectionOptions {
                if let group = var_asset.mediaSelectionGroup(forMediaCharacteristic: AVMediaCharacteristic.audible) {
                    if let option = group.options.first {
                        palyerItem.select(option, in: group)
                    }
                }
            }
            let palyerLayer = AVPlayerLayer()
            palyer.replaceCurrentItem(with: palyerItem)
            palyerLayer.videoGravity = .resizeAspectFill
            palyerLayer.player = palyer
            
            DispatchQueue.main.async {
                var_endTime = Int(palyer.currentItem?.asset.duration.seconds ?? 0).ht_formatTimeLine()
                var_during = palyer.currentItem?.asset.duration.seconds ?? 0
                ht_seek(second: Float64(var_seekTime))
                if (!var_showInterstitialAd && !var_showRewardedAd) {
                    var_palyer.play()
                    var_isSuspend = false
                    var_isShowControls = false
                }
            }
        }
    }
    
    // 精确定位
    func ht_seek(second: Float64) {
        let var_timeScale = var_palyer.currentItem?.asset.duration.timescale
        let var_time = CMTimeMakeWithSeconds(second, preferredTimescale: var_timeScale ?? 1)
        var_palyer.seek(to: var_time, toleranceBefore: CMTime.zero, toleranceAfter: CMTime.zero)
    }
}
